home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Misc / Crossword / Source / PlainSquare.m < prev    next >
Text File  |  1992-10-12  |  4KB  |  245 lines

  1. /*
  2.  
  3. File PlainSquare.m
  4.  
  5. Squares are the variables that guide the search.  This file implements simple squares for plain depth first search.
  6.  
  7. */
  8.  
  9. #import <appkit/appkit.h>
  10.  
  11. #import "Plain.h"
  12. #import "Puzzle.h"
  13. #import "Crossword.h"
  14. #import "CrosswordSquare.h"
  15. #import "Inspector.h"
  16.  
  17.  
  18. /* ————————————————————————————————————————————————————————————————————————————  */
  19.  
  20.  
  21. #define position(i)        ((wordPosition *) [words  elementAt: i])
  22. #define forword(c)        ((c) == WILDCARD ? (c):(c) + 'a')
  23. #define forcell(c)        ((c) == WILDCARD ? EMPTY:(c) + 'A')
  24.  
  25.  
  26. /* ————————————————————————————————————————————————————————————————————————————  */
  27.  
  28.  
  29. @implementation PlainSquare
  30.  
  31. - (float) efficiency    {    return efficiency;    }
  32.  
  33.  
  34. /* ————————————————————————————————————————————————————————————————————————————  */
  35.  
  36.  
  37. - initPuzzle: (id) thePuzzle  cell: (id) theCell
  38. {
  39.     [super  init];
  40.     
  41.     puzzle = thePuzzle;
  42.     cell = theCell;
  43.     letter = WILDCARD;
  44.     tried = 0;
  45.     words = [[Storage  alloc]
  46.                 initCount: 0  elementSize: sizeof(wordPosition)  description: ""];
  47.     
  48.     return self;
  49. }
  50.  
  51.  
  52. - free
  53. {
  54.     [words  free];
  55.     [super  free];
  56.     
  57.     return self;
  58. }
  59.  
  60.  
  61. - addToWord: (id) word  at: (int) i
  62. {
  63.     wordPosition    position;
  64.     
  65.     position.word = word;
  66.     position.i = i;
  67.     [words  addElement: &position];
  68.     
  69.     return self;
  70. }
  71.  
  72.  
  73. - startOver
  74. {
  75.     return self;
  76. }
  77.  
  78.  
  79. /* ————————————————————————————————————————————————————————————————————————————  */
  80.  
  81.  
  82. - setStatus: (int) flag
  83. {
  84.     status |= flag;
  85.     [self  adjustColor];
  86.     
  87.     return self;
  88. }
  89.  
  90.  
  91. - clearStatus: (int) flag
  92. {
  93.     status &= ~flag;
  94.     [self  adjustColor];
  95.     
  96.     return self;
  97. }
  98.  
  99.  
  100. - hilight
  101. {
  102.     [self  setStatus: HILIGHT];
  103.     [[puzzle  getCrossword]  drawCellInside: cell];
  104.     
  105.     return self;
  106. }
  107.  
  108.  
  109. - unhilight
  110. {
  111.     [self  clearStatus: HILIGHT];
  112.     [[puzzle  getCrossword]  drawCellInside: cell];
  113.     
  114.     return self;
  115. }
  116.  
  117.  
  118. - adjustColor
  119. {
  120.     int        i, n;
  121.     
  122.     n = status & ~(status - 1);
  123.     i = 0;
  124.     while (n > 0)
  125.     {
  126.         i++;
  127.         n >>= 1;
  128.     }
  129.     
  130.     [cell  setColor: [[puzzle  getInspector]  getColor: i]];
  131.     return self;
  132. }
  133.  
  134.  
  135. /* ————————————————————————————————————————————————————————————————————————————  */
  136.  
  137.  
  138. - (BOOL) fillNext
  139. {
  140.     char    choice;
  141.     
  142.     if ((choice = [self  chooseLetter]) == WILDCARD) [self  clear];
  143.     [[self  setLetter: choice]  show];
  144.     
  145.     return (letter == WILDCARD) ? NO:YES;
  146. }
  147.  
  148.  
  149. - erase
  150. {
  151.     [[[self  clear]  setLetter: WILDCARD]  show];
  152.     return self;
  153. }
  154.  
  155.  
  156. - clear
  157. {
  158.     letter = WILDCARD;
  159.     tried = 0;
  160.     
  161.     return self;
  162. }
  163.  
  164.  
  165. - show
  166. {
  167.     [[puzzle  getCrossword]  putLetter: forcell(letter)  inSquare: cell];
  168.     DPSFlush();
  169.     
  170.     return self;
  171. }
  172.  
  173.  
  174. - setLetter: (char) theLetter
  175. {
  176.     wordPosition    * position;
  177.     int                i;
  178.     
  179.     if ((letter = theLetter) != WILDCARD) tried |= (1 << letter);
  180.     i = [words  count];
  181.     
  182.     while (i--)
  183.     {
  184.         position = position(i);
  185.         [position->word  changeLetter: position->i  to: forword(letter)];
  186.     }
  187.     
  188.     return self;
  189. }
  190.  
  191.  
  192. - (char) chooseLetter
  193. {
  194.     int        i, max;
  195.     char    best;
  196.     BOOL    findbest;
  197.     
  198.     best = WILDCARD;
  199.     findbest = [[puzzle  getInspector]  getOption: BESTLETTER];
  200.     
  201.     for (max = 0, i = 0; i < LETTERS; i++)
  202.     if ((count[i] > max) && !(tried & (1 << i)))
  203.     {
  204.         max = count[i];
  205.         best = i;
  206.         if (!findbest) break;
  207.     }
  208.     
  209.     return best;
  210. }
  211.  
  212.  
  213. /* ————————————————————————————————————————————————————————————————————————————  */
  214.  
  215.  
  216. - update
  217. {
  218.     wordPosition    * position;
  219.     countTable        table;
  220.     int                i, j;
  221.     
  222.     if (letter == WILDCARD)
  223.     {
  224.         for (j = 0; j < LETTERS; j++) count[j] = 1;
  225.         i = [words  count];
  226.         
  227.         while (i--)
  228.         {
  229.             position = position(i);
  230.             table = [position->word  getCount];
  231.             for (j = 0; j < LETTERS; j++) count[j] *= table[position->i][j];
  232.         }
  233.         
  234.         for (i = 0, j = 0; j < LETTERS; j++) i += (count[j] != 0);
  235.         if ([[puzzle  getInspector]  getOption: BESTSQUARE])
  236.         
  237.                 efficiency = 1.0 / (i + 1.0);    else
  238.                 efficiency = (i == 0) + 1.0;
  239.     }
  240.     
  241.     return self;
  242. }
  243.  
  244.  
  245. @end